<?php
/**
 * yumao
 * 2018-8-3
 * 监控报警条件url模式（营销邮件）
 */
namespace app\controllers;

use yii;
class MonitorMarketingMailFromUrlController extends \app\base\Controller
{   
    
    /**
     * 注册数据相关
     * @param type $site
     * @return type
     */
    private function esReg($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        $nowTime = time();
        $sevenDaysAgoTime = $nowTime - 7*24*3600;
        // 7天之内注册的用户对比
        $filterArr7Reg = [
            'filters'=>[
                [
                    "field"=>"regTime",
                    "operator"=>"must",
                    "type"=>"range",
                    "values" =>[$sevenDaysAgoTime, $nowTime]
                ]     
            ]
        ];

        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArr7Reg); // 从es中搜索的数据

        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sql7Reg = "select count(*) as cnt from user_{$site} as user where user.reg_time >= {$sevenDaysAgoTime} and user.reg_time <= {$nowTime} and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sql7Reg)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 100) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端7天之内注册的用户数据和emp数据库相差超过100条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    
    /**
     * 登录数据相关
     * @param type $site
     */
    private function esLogin($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        $nowTime = time();
        $sevenDaysAgoTime = $nowTime - 7*24*3600;
        // 7天之内登录的用户对比
        $filterArr7Login = [
            'filters'=>[
                [
                    "field"=>"lastLogin",
                    "operator"=>"must",
                    "type"=>"range",
                    "values" =>[$sevenDaysAgoTime, $nowTime]
                ]     
            ]
        ];
        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArr7Login); // 从es中搜索的数据

        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sql7Login = "select count(*) as cnt from user_{$site} as user where user.last_login >= {$sevenDaysAgoTime} and user.last_login <= {$nowTime} and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sql7Login)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 500) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端7天之内登录的用户数据和emp数据库相差超过500条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    
    /**
     * 订单数据相关
     * @param type $site
     */
    private function esOrder($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        $nowTime = time();
        $sevenDaysAgoTime = $nowTime - 7*24*3600;
        // 7天之内下单的用户对比
        $filterArr7Order = [
            'filters'=>[
                [
                    "field"=>"lastOrderTime",
                    "operator"=>"must",
                    "type"=>"range",
                    "values" =>[$sevenDaysAgoTime, $nowTime]
                ]     
            ]
        ];
        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArr7Order); // 从es中搜索的数据

        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sql7Order = "select count(*) as cnt from user_{$site} as user where user.last_order_time >= {$sevenDaysAgoTime} and user.last_order_time <= {$nowTime} and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sql7Order)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 50) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端7天之内下单的用户数据和emp数据库相差超过50条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    
    /**
     * 发送数据相关
     * @param type $site
     */
    private function esSend($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        $nowTime = time();
        $sevenDaysAgoTime = $nowTime - 7*24*3600;
        // 7天之内发送的用户对比 (发送数据量比较大会延迟一段时间所以我们取3小时之前的数据对比)
        $startTime = $sevenDaysAgoTime - 3*3600;
        $endTime = $nowTime - 3*3600;
        $filterArr7Send = [
            'filters'=>[
                [
                    "field"=>"lastSentTime",
                    "operator"=>"must",
                    "type"=>"range",
                    "values" =>[$startTime, $endTime]
                ]     
            ]
        ];
        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArr7Send); // 从es中搜索的数据

        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sql7Send = "select count(*) as cnt from user_{$site} as user where user.last_sent_time >= {$startTime} and user.last_sent_time <= {$endTime} and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sql7Send)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 1000) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端7天之内发送的用户数据和emp数据库相差超过1000条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    
    /**
     * 订阅数据相关
     * @param type $site
     */
    private function esReceivedPromo($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        // 订阅用户
        $filterArrReceivedPromo = [
            'filters'=>[
                [
                    "field"=>"isReceivedPromo",
                    "values" =>[1]
                ]     
            ]
        ];
        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArrReceivedPromo); // 从es中搜索的数据
        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sqlReceivedPromo = "select count(*) as cnt from user_{$site} as user where user.is_received_promo = 1 and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sqlReceivedPromo)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 20) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端订阅用户数据和emp数据库相差超过20条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    
    /**
     * 内测相关
     * @param type $site
     */
    private function esTest($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        // 内测用户
        $filterArrTest = [
            'filters'=>[
                [
                    "field"=>"isTest",
                    "values" =>[1]
                ]     
            ]
        ];
        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArrTest); // 从es中搜索的数据
        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sqlTest = "select count(*) as cnt from user_{$site} as user where user.is_test = 1 and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sqlTest)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 20) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端内测用户数据和emp数据库相差超过20条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    
    /**
     * 硬弹数据相关
     * @param type $site
     */
    private function esBound($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        // 弹出用户
        $filterArrBound = [
            'filters'=>[
                [
                    "field"=>"isBound",
                    "values" =>[1]
                ]     
            ]
        ];
        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArrBound); // 从es中搜索的数据
        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sqlBound = "select count(*) as cnt from user_{$site} as user where user.is_bound = 1 and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sqlBound)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 20) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端弹出用户数据和emp数据库相差超过20条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    
    /**
     * 投诉相关
     * @param type $site
     */
    private function esComplaint($site)
    {
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        // 投诉用户
        $filterArrComplaint = [
            'filters'=>[
                [
                    "field"=>"isComplaint",
                    "values" =>[1]
                ]     
            ]
        ];
        $esSearchCount = Yii::$app->es->setSite($site)->count($filterArrComplaint); // 从es中搜索的数据
        // 由于es端不存黑名单和注销的用户所以在mysql中排除时我们也把这个去除方便比较
        $sqlComplaint = "select count(*) as cnt from user_{$site} as user where user.is_complaint = 1 and is_del=0 and is_block=0";
        $mysqlSearchCount = yii::$app->db->createCommand($sqlComplaint)->queryScalar();
        $differCount = abs($mysqlSearchCount-$esSearchCount);
        if ($differCount > 20) {
            $returnInfo['flag'] = 0;
            $returnInfo['info'] .= "{$site}网站es端投诉用户数据和emp数据库相差超过20条，具体相差：{$differCount}条";
        }
        return $returnInfo;
    }
    /**
     * 监控es数据和我们这边的数据差异
     */
    public function actionMonitorEsData()
    {
        $mothod = strtolower(Yii::$app->request->getMethod());
        $formData = Yii::$app->request->$mothod();
        $returnInfo = ['is_sure_flag'=>1,'info'=>'','flag'=>1];
        if (empty($formData['deal_site_name'])) {
            $returnInfo['is_sure_flag'] = 1;
            $returnInfo['flag'] = 0;
            $returnInfo['info'] = "监控项自身配置有问题没有传递网站名称";
            echo json_encode($returnInfo);
            exit;
        } 
        
        if (empty($formData['action'])) {
            $returnInfo['is_sure_flag'] = 1;
            $returnInfo['flag'] = 0;
            $returnInfo['info'] = "监控项自身配置有问题没有传递监控行为";
            echo json_encode($returnInfo);
            exit;
        }
        
        switch($formData['action']) {
            case "reg": 
                $returnInfo = $this->esReg($formData['deal_site_name']);
                break;
            case "login":
                $returnInfo = $this->esLogin($formData['deal_site_name']);
                break;
            case "order":
                $returnInfo = $this->esOrder($formData['deal_site_name']);
                break; 
            case "send":
                $returnInfo = $this->esSend($formData['deal_site_name']);
                break; 
            case "receivedpromo":
                $returnInfo = $this->esReceivedPromo($formData['deal_site_name']);
                break; 
            case "test":
                $returnInfo = $this->esTest($formData['deal_site_name']);
                break; 
            case "bound":
                $returnInfo = $this->esBound($formData['deal_site_name']);
                break; 
            case "complaint":
                $returnInfo = $this->esComplaint($formData['deal_site_name']);
                break; 
            default :
                $returnInfo = ['is_sure_flag'=>1,'info'=>'监控项自身配置有问题监控行为有问题','flag'=>0];
                break;
        }
        echo json_encode($returnInfo);
        exit;
    }
    
    /**
     * 检查是否下载文件控制器
     * 查看当天日志文件是否返回并解压成功
     */
    public function actionMonitorEmarsysLogData()
    {
        $curBjTime = \yii::$app->bjTime->time();
        $curDay =\yii::$app->bjTime->date("Ymd",$curBjTime);
        $beforeOneDay = \yii::$app->bjTime->date("Ymd",$curBjTime-24*3600);
        $downLoadFileName = $beforeOneDay.'000000_TO_'.$curDay.'000000.zip'; 
        $fileUnZipName = $beforeOneDay.'000000_TO_'.$curDay.'000000'; 
        $dirPath = ROOT_PATH.'/bounces_data/emarsys_data/';
        $returnInfo = [];
        // is_sure_flag代表对当前结果是不是确定一定要重试或者告警或者正常
        if (file_exists($dirPath.$fileUnZipName) && !empty(array_diff(scandir($dirPath.$fileUnZipName),['..','.']))) { // 文件夹存在并且不为空说明正常
            $returnInfo['flag'] = 1;
            $returnInfo['info'] = "解压后文件夹存在并且正常";
            $returnInfo['is_sure_flag'] = 1;
            echo json_encode($returnInfo);
            exit;
        }
        if (!file_exists($dirPath.$downLoadFileName)) {    // 压缩文件不存在，不正常
            $returnInfo['flag'] = 0;
            $returnInfo['info'] = "压缩文件不存在";
            $returnInfo['is_sure_flag'] = 1;
            echo json_encode($returnInfo);
            exit;
        }
        
        if (file_exists($dirPath.$downLoadFileName) && !file_exists($dirPath.$fileUnZipName)) { // 压缩文件存在 但是解压后的文件夹不存在 
            // 有可能是正在下载过程中,10秒后判断文件大小是不是有发生变化
            $sizeDownLoadFile1 = filesize($dirPath.$downLoadFileName);
            sleep(10);
            $sizeDownLoadFile2 = filesize($dirPath.$downLoadFileName);
            if ($sizeDownLoadFile1 != $sizeDownLoadFile2) {
                $returnInfo['flag'] = 1;
                $returnInfo['info'] = "文件正在下载过程当中";
                $returnInfo['is_sure_flag'] = 0;
                echo json_encode($returnInfo);
                exit;
            }
            
            // 也有可能是刚刚下载完，还没开始解压，10秒中过后压缩文件大小没有变化并且解压文件夹还不存在说明压缩文件下载有问题
            if (!file_exists($dirPath.$fileUnZipName)) {
                $returnInfo['flag'] = 0;
                $returnInfo['info'] = "压缩文件下载异常";
                $returnInfo['is_sure_flag'] = 1;
                echo json_encode($returnInfo);
                exit;
            } else {
                $returnInfo['flag'] = 1;
                $returnInfo['info'] = "文件正在解压";
                $returnInfo['is_sure_flag'] = 0;
                echo json_encode($returnInfo);
                exit;
            }            
        } else { // 压缩文件存在，解压文件也存在，但是解压后文件夹为空的情况
            sleep(10); // 10秒后再判断文件夹是否为空
            $dirFileUnZipInfo = scandir($dirPath.$fileUnZipName);
            if (empty(array_diff($dirFileUnZipInfo,['..','.']))) {
                $returnInfo['flag'] = 0;
                $returnInfo['info'] = "解压失败";
                $returnInfo['is_sure_flag'] = 1;
                echo json_encode($returnInfo);
                exit;
            } else {
                $returnInfo['flag'] = 1;
                $returnInfo['info'] = "文件正在解压";
                $returnInfo['is_sure_flag'] = 0;
                echo json_encode($returnInfo);
                exit;
            }
        }
    }
}